var __importDefault =
  (this && this.__importDefault) ||
  function (mod) {
    return mod && mod.__esModule ? mod : { default: mod };
  };
const fs = require("fs");
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebpackObfuscatorPlugin = void 0;
const webpack_1 = require("webpack");
const javascript_obfuscator_1 = __importDefault(
  require("javascript-obfuscator")
);
const multimatch_1 = __importDefault(require("multimatch"));
const transferSourceMap = require("multi-stage-sourcemap").transfer;
class WebpackObfuscatorPlugin {
  constructor(options = {}, excludes) {
    this.options = options;
    this.excludes = [];
    this.excludes = this.excludes.concat(excludes || []);
  }
  apply(compiler) {
    const isDevServer = process.argv.find((v) =>
      v.includes("webpack-dev-server")
    );
    if (isDevServer) {
      console.info(
        "JavascriptObfuscator is disabled on webpack-dev-server as the reloading scripts ",
        "and the obfuscator can interfere with each other and break the build"
      );
      return;
    }
    const pluginName = this.constructor.name;
    compiler.hooks.compilation.tap(pluginName, (compilation) => {
      compilation.hooks.processAssets.tap(
        {
          name: "WebpackObfuscator",
          stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
        },
        (assets) => {
          let identifiersPrefixCounter = 0;
          const sourcemapOutput = {};
          compilation.chunks.forEach((chunk) => {
            chunk.files.forEach((fileName) => {
              const { source: inputSource, map: inputSourceMap } =
                assets[fileName].sourceAndMap();
              const { obfuscatedSource, obfuscationSourceMap } = this.obfuscate(
                inputSource,
                // source,
                fileName,
                identifiersPrefixCounter
              );
              if (this.options.sourceMap && inputSourceMap) {
                sourcemapOutput[fileName] = obfuscationSourceMap;
                const transferredSourceMap = transferSourceMap({
                  fromSourceMap: obfuscationSourceMap,
                  toSourceMap: inputSourceMap,
                });
                const finalSourcemap = JSON.parse(transferredSourceMap);
                finalSourcemap["sourcesContent"] =
                  inputSourceMap["sourcesContent"];
                assets[fileName] = new webpack_1.sources.SourceMapSource(
                  obfuscatedSource,
                  fileName,
                  finalSourcemap
                );
              } else {
                assets[fileName] = new webpack_1.sources.RawSource(
                  obfuscatedSource,
                  false
                );
              }
              identifiersPrefixCounter++;
            });
          });
        }
      );
    });
  }
  shouldExclude(filePath) {
    return (0, multimatch_1.default)(filePath, this.excludes).length > 0;
  }
  extractSourceAndSourceMap(asset) {
    if (asset.sourceAndMap) {
      const { source, map } = asset.sourceAndMap();
      return { inputSource: source, inputSourceMap: map };
    } else {
      return {
        inputSource: asset.source(),
        inputSourceMap: asset.map(),
      };
    }
  }
  obfuscate(javascript, fileName, identifiersPrefixCounter) {
    const obfuscationResult = javascript_obfuscator_1.default.obfuscate(
      javascript,
      Object.assign(
        {
          identifiersPrefix: `${WebpackObfuscatorPlugin.baseIdentifiersPrefix}${identifiersPrefixCounter}`,
          inputFileName: fileName,
          sourceMapMode: "separate",
          sourceMapFileName: fileName + ".map",
        },
        this.options
      )
    );
    return {
      obfuscatedSource: obfuscationResult.getObfuscatedCode(),
      obfuscationSourceMap: obfuscationResult.getSourceMap(),
    };
  }
}
module.exports = WebpackObfuscatorPlugin;
